package com.jsn.buildbase.weather

import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.Rect
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ListAdapter
import android.widget.TextView
import androidx.core.view.forEach
import androidx.core.view.get
import androidx.databinding.BindingAdapter
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import androidx.fragment.app.viewModels
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.observe
import androidx.navigation.fragment.navArgs
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.jsn.baselibx.widget.BaseRVAdapter
import com.jsn.baselibx.widget.BaseViewHolder
import com.jsn.buildbase.BR

import com.jsn.buildbase.R
import com.jsn.buildbase.databinding.FragmentDetailBinding
import com.jsn.buildbase.utilities.InjectorUtil
import javax.inject.Inject

class DetailFragment : Fragment() {

    companion object {
        fun newInstance() = DetailFragment()
    }

    val safeArgs=5

    val eventId
    get() = 5


    private val  viewModel: DetailViewModel by viewModels {
        InjectorUtil.detailViewModelFactory(eventId) // at run time
    }

    lateinit var adapter: BaseRVAdapter<City,BaseViewHolder>



    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        //inflater.inflate(R.layout.fragment_detail, container, false)

        val binding: FragmentDetailBinding = FragmentDetailBinding.inflate(inflater, container, false)
            .apply {
                lifecycleOwner=viewLifecycleOwner
                viewModel=this@DetailFragment.viewModel

            }
        initAdapter()


        binding.rv.layoutManager=LinearLayoutManager(context)

        viewModel.listData.observe(viewLifecycleOwner){list->

            if(binding.rv.adapter==null){
                binding.rv.adapter=adapter
            }

            binding.rv.clearDecorations()
            if(list.isNotEmpty()) {
                binding.rv.addItemDecoration(HeaderDecoration(list))
            }
            adapter.setData(list as ArrayList<City>)

        }

        return binding.root
    }

    private fun initAdapter() {
        adapter=object:BaseRVAdapter<City,BaseViewHolder>(context!!){
            override fun layoutResId(viewType: Int): Int {
                return R.layout.item_simple_text_1
            }

            override fun holderInstance(binding: ViewDataBinding): BaseViewHolder {
                return object:BaseViewHolder(binding){
                    override fun bindData(item: Any?) {
                        super.bindData(item)
                    }

                    override fun doClick(view: View) {
                        super.doClick(view)
                    }
                }
            }

        }
    }




    inner class CityViewHolder(val binding:ViewDataBinding)
        :RecyclerView.ViewHolder(binding.root){
       fun bind(city:City){
           binding.setVariable(BR.item,city)
           binding.setVariable(BR.doClick,object:View.OnClickListener{
               override fun onClick(v: View?) {
               }

           })
           binding.executePendingBindings()
       }
    }

    object cityDiff : DiffUtil.ItemCallback<City>() {
        override fun areItemsTheSame(oldItem: City, newItem: City): Boolean {
            return oldItem.province == newItem.province &&
                    oldItem.name == newItem.name
        }

        override fun areContentsTheSame(oldItem: City, newItem: City) = oldItem == newItem
    }





    inner class HeaderDecoration(val data:List<City>):RecyclerView.ItemDecoration(){

        val proviceSlot =
            data.mapIndexed({ index, city -> index to city.province }) //pair<index,province>
                .distinctBy { it.second } //<0,zhejiang>,<5,shanghai>.....
                .toMap()

        val paint=Paint().apply {
            color= Color.BLUE
            strokeWidth=1f
        }

        val textSize1:Float=40f //todo add declare stylable

        val paint1=Paint().apply {
            color= Color.RED
            strokeWidth=1f
            textSize=textSize1
        }



        override fun getItemOffsets(
            outRect: Rect,
            view: View,
            parent: RecyclerView,
            state: RecyclerView.State
        ) {
            super.getItemOffsets(outRect, view, parent, state)
            val childAdapterPosition = parent.getChildAdapterPosition(view)
            outRect.top=if (proviceSlot.containsKey(childAdapterPosition)) 100 else 0
        }

        override fun onDraw(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {

            val layoutManager = parent.layoutManager ?: return
            val centerX = parent.width / 2f
            parent.forEach { child->
                if(child.top<parent.height && child.bottom>0){
                    //child visible
                    if(proviceSlot.containsKey(parent.getChildAdapterPosition(child))){
                        //has header so we just draw header
                        val dx=0f
                        val dy=(layoutManager.getDecoratedTop(child)
                        +child.translationY).toFloat()
                        val province: String? = proviceSlot.get(parent.getChildAdapterPosition(child))
                        c.withTranslation (dx,dy){
                            val rect = Rect(0, 0, parent.width, 100)
                            c.drawRect(rect,paint)
                            c.drawText(province ?:"",centerX-(province!!.length*textSize1)/4,50f+textSize1/2,paint1)
                        }
                    }
                }
            }
        }

        override fun onDrawOver(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {
            super.onDrawOver(c, parent, state)
            if(data.size<1) return
            val layoutManager = parent.layoutManager as? LinearLayoutManager ?: return

            val centerX = parent.width / 2f


            val child = parent.getChildAt(0)

            val adapterPosition = parent.getChildAdapterPosition(child!!)
            //province now
            val province = data.get(adapterPosition).province

            val decoratedBottom = layoutManager.getDecoratedBottom(child)+child.translationY

            if(decoratedBottom<100 && adapterPosition+1<=data.size-1 && !data.get(adapterPosition+1).province.equals(province)){

                val offsetY = 100 - decoratedBottom
                c.withTranslation (0f,-offsetY){
                    val rect = Rect(0, 0, parent.width, 100)
                    c.drawRect(rect,paint)
                    c.drawText(province ?:"",centerX-(province!!.length*textSize1)/4,50f+textSize1/2,paint1)
                }

            }else{
                //draw
                val dx=0f
                val dy=0f
                c.withTranslation (dx,dy){
                    val rect = Rect(0, 0, parent.width, 100)
                    c.drawRect(rect,paint)
                    c.drawText(province ?:"",centerX-(province!!.length*textSize1)/4,50f+textSize1/2,paint1)
                }
            }


        }

    }

}


fun RecyclerView.clearDecorations() {
    if (itemDecorationCount > 0) {
        for (i in itemDecorationCount - 1 downTo 0) {
            removeItemDecorationAt(i)
        }
    }
}

inline fun Canvas.withTranslation(
    x: Float = 0.0f,
    y: Float = 0.0f,
    block: Canvas.() -> Unit
) {
    val checkpoint = save()
    translate(x, y)
    try {
        block()
    } finally {
        restoreToCount(checkpoint)
    }
}





@BindingAdapter("longValue")
fun bindLong(view: View,long:Long){
    val textView = view as TextView
    textView.text=long.toString()
}
